#pragma warning(disable: 4786)
#include "../Parse.h"
using namespace compiler;
namespace compiler_test{

	void log_mcode_datas(list<Token*> &_data){
		list<Token*>::iterator mit=_data.begin();

		while(mit!=_data.end())
		{
			Token *t=*mit;
			log->info("\n");
			if(t->cons) log->info("[const]");
			if(t->glo_id) log->info("[global]");
			switch(t->type)
			{
				case TInt: { log->info("[int]"); break; }
			    case TFloat: { log->info("[float]"); break; }
			    case TChar: { log->info("[char]"); break; }
				case TString:{log->info("[string]"); break;}
			}
			log->info(t->s);
			mit++;
		}	
	}
	void log_mcode_codes(list<Func_token*> &_code){
		list<Func_token*>::iterator mit=_code.begin();

		while(mit!=_code.end())
		{
			Func_token *t=*mit;
			log->info("\nINFO:");
			log->info("function:");
			log->info(t->s);
			log->info("(");
			for(int i=1;i<=t->argc;i++)
			{
				switch(t->argv[i]->type)
				{
					case TInt:{log->info("[int]"); break;}
					case TFloat:{log->info("[float]"); break;}
					case TChar:{log->info("[char]"); break;}
				    case TVoid:{log->info("[void]"); break;}
				}
			}
			log->info(")\n");
			
			log->info("return:");
			switch(t->type)
			{
				case TInt:{log->info("[int]"); break;}
				case TFloat:{log->info("[float]"); break;}
				case TChar:{log->info("[char]"); break;}
				case TVoid:{log->info("[void]"); break;}
			}
			log->info("\n");
			list<Mcode*> &codes=t->codes;

			list<Mcode*>::iterator it=codes.begin();
			Mcode *m;
			while(it!=codes.end())
			{
				m=*it;
				if(m->lable!=NULL)
				{
					
					log->info(m->lable->to_string());
					log->info(":");
				}
				
				if(m->e1!=NULL)
				{
					if(m->e1->cons)
						log->info(m->e1->value);
					else
						log->info(m->e1->s);
				}
				if(m->op!=NULL)
				{
					switch(m->op)
					{
						case ADD:{log->info("+"); break;}
						case SUB:{log->info("-"); break;}
						case MUL:{log->info("*"); break;}
					    case DIV:{log->info("/"); break;}
						case JE:{log->info("=="); break;}
						case JNE:{log->info("!="); break;}
						case JL:{log->info(">"); break;}
						case JLE:{log->info(">="); break;}
						case JB:{log->info("<"); break;}
						case JBE:{log->info("<="); break;}
						case JMP:{log->info("jmp"); break;}
						case CALL:{log->info("call"); break;}
						case PARAM:{log->info("param"); break;}
						case ASSIGN:{log->info("=:"); break;}
						case RET:{log->info("return"); break;}
						case TOINT:{log->info("(int)"); break;}
						case TOFLOAT:{log->info("(float)"); break;}
						case READ:{log->info("read"); break;}
						case WRITE:{log->info("write"); break;}
						case NULLOP:{log->info(" ");break;}
					}
				}
				if(m->e2!=NULL)
				{
					if(m->e2->cons)
						log->info(m->e2->value);
					else
						log->info(m->e2->s);
				}
				if(m->r!=NULL)
				{
					log->info(" ");
					log->info(m->r->s);
				}
				if(m->jl!=NULL)
				{
					log->info(m->jl->to_string());
				}
				log->info("\n");
				it++;
			}
			mit++;
		}	
	}

	void parser_test(){	
	char* file_in="C:\\Workc++\\Compiler\\s.txt";
	string file_name;
	cin>>file_name;
	Lexer l(file_name.c_str());
	Parser p(l);
	
	list<Token*> _data;
	list<Func_token*> _code;
	p.init(_data,_code);
	
	p.programing();
	
	log_mcode_datas(_data);
	log_mcode_codes(_code);
	
	log->wait();
}
}